home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_c / cug106 / iofun.asm < prev    next >
Assembly Source File  |  1984-06-14  |  9KB  |  428 lines

  1. ;                iofun.asm
  2. ;
  3. ;    Copyright (C) 1980, M J Maney
  4. ;
  5. ;    First created 8/30/80
  6. ;    Last revised 9/26/80 15:25
  7. ;
  8. ;    Tested and installed xx/xx/xx
  9. ;
  10. ;    Since I/O is such a big part of most programs, it would seem logical
  11. ;    to desire your I/O functions to be as efficent as possible. This
  12. ;    especially applies to the buffered character I/O that C uses for
  13. ;    disk communication. These routines can dominate the run-time of
  14. ;    programs that don't do extensive computation, and may affect the
  15. ;    speed of some that are rather heavily computational. Thus they are
  16. ;    being coded here in assembler.
  17. ;*
  18. ;*    I have removed the 'overlapping' code reffered to in read.me,
  19. ;*    but this is still entirely untested. You have been warned.
  20. ;
  21. ;
  22.     maclib    crl
  23. ;
  24. ;
  25. ;    getc(iobuf)
  26. ;    FILBUF *iobuf;
  27. ;
  28. ;    This is the basic C character I/O function. It returns one byte from
  29. ;    the buffered file described by the FILBUF that iobuf points to,
  30. ;    and takes care of the buffer management. The structure of the
  31. ;    file buffer is:
  32. ;
  33. ;    byte offset        what's there
  34. ;
  35. ;    0,1            file's 'file descriptor', used in calls
  36. ;                to read, etc
  37. ;    2,3            nleft, the number of bytes left before
  38. ;                the buffer is depleted and must be filled
  39. ;    4,5            nextp, the pointer into the buffer
  40. ;    6,133            buff, the 128 byte buffer
  41. ;
  42. ;    This function is operationally identical to the C version in the
  43. ;    "stdlib1.c" file distributed with the 1.32 release of the BDS
  44. ;    compiler, and except for a little re-arrangement at the very end,
  45. ;    it is a straight hand translation from that source.
  46. ;
  47.     PROC    GETC,<GETCHAR,READ>
  48.     lhld    ARG1
  49.     mov    a,h
  50.     ora    l
  51.     BNZ    getc1        ;if (iobuf == 0)
  52.     BSR    GETCHAR
  53.     ret            ;    return getchar();
  54. getc1    inx    h
  55.     inx    h
  56.     mov    e,m
  57.     inx    h
  58.     mov    d,m
  59.     push    d
  60.     dcx    d
  61.     mov    m,d
  62.     dcx    h
  63.     mov    m,e
  64.     pop    d
  65.     mov    a,d
  66.     ora    e
  67.     BZ    getc2        ;if (iobuf->nleft-- .NE. 0)
  68.     inx    h
  69.     inx    h
  70.     mov    e,m
  71.     inx    h
  72.     mov    d,m
  73.     push    d
  74.     inx    d
  75.     mov    m,d
  76.     dcx    h
  77.     mov    m,e
  78.     pop    h
  79.     mov    l,m
  80.     mvi    h,0
  81.     ret            ;    return *iobuf->nleft--;
  82. getc2    dcx    h
  83.     mov    d,m
  84.     dcx    h
  85.     mov    e,m
  86.     push    h
  87.     xchg
  88.     shld    ARG1
  89.     pop    h
  90.     push    h
  91.     lxi    d,6
  92.     dad    d
  93.     shld    ARG2
  94.     lxi    h,1
  95.     shld    ARG3
  96.     BSR    READ
  97.     mov    a,h
  98.     ora    a
  99.     BM    getc3
  100.     ora    l
  101.     BNZ    getc4        ;if (read(iobuf->fd,iobuf->buff,1) <= 0)
  102. getc3    pop    h
  103.     lxi    h,-1
  104.     ret            ;    return ERR;
  105. getc4    pop    h
  106.     inx    h
  107.     inx    h
  108.     lxi    d,127
  109.     mov    m,e
  110.     inx    h
  111.     mov    m,d        ;iobuf->nleft = 127;
  112.     inx    h
  113.     inx    h
  114.     inx    h
  115.     mov    d,h
  116.     mov    e,l
  117.     mov    a,m        ;a = *iobuf->buff;
  118.     inx    d
  119.     dcx    h
  120.     mov    m,d
  121.     dcx    h
  122.     mov    m,e        ;iobuf->nextp = iobuf->buff - 1;
  123.     mov    l,a
  124.     mvi    h,0
  125.     ret            ;return a;
  126.     PEND    GETC
  127. "≈E┼!    DM═ ┴┼!    DM═┴├z├╣├╣┼!    DM═┴╔2PSlì₧¡│╣┐┼╦╬▄ΓΦε⌠·    #0=@Rqæ¢╢├╞█Φ#CMhuxèó¡▒┤╖┴CURSO╥SAVCU╥PUTCHA╥PUT╙RSTCU╥INDE╪≤├├├├├├├*≈Eδ`is#r*∙Eδ!    s#r*√Eδ!    s#r`i~#foσ!    ~#fo"∙Eß"≈E┼!    DM═┴┼!    DM═┴!"≈E┼!    DM═    ┴!w├z#3"≈E┼!    DM═ ┴!    ~#fo"≈E┼!    DM═ ┴┼!    DM═┴┼!    DM═┴!"≈E┼!    DM═    ┴!╦;                machine.asm
  128. ;
  129. ;    Copyright (C) 1980, M J Maney
  130. ;
  131. ;    First created 8/28/80
  132. ;    Last revised 8/29/80 15:30
  133. ;
  134. ;    Tested and installed 8/29/80 16:15
  135. ;
  136. ;    This file contains some assembler functions for BDS C. These functions
  137. ;    are assorted little ditties for doing low-level operations such as
  138. ;    filling/moving/exchanging blocks of memory.
  139. ;
  140.     maclib    crl
  141. ;
  142. ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
  143. ;
  144. ;    movmem        xchmem        fillbyte    fillword
  145. ;    inp        outp        peek        poke
  146. ;    peekw        pokew
  147. ;
  148. ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
  149. ;
  150. ;
  151. ;    movmem(src,des,n)
  152. ;    char *src,*des;
  153. ;    uint n;
  154. ;
  155. ;    Move a block of memory from src to des: the block is n bytes long.
  156. ;    This function allows for moves of overlapping blocks by moving in
  157. ;    either ascending or descending order as required.
  158. ;
  159.     PROC    MOVMEM
  160.     lhld    ARG3
  161.     mov    b,h
  162.     mov    c,l        ;n to BC
  163.     lhld    ARG2
  164.     xchg            ;des to DE
  165.     lhld    ARG1        ;src to HL
  166.     BSR    movmem4        ;test for direction to use in moving
  167.     BC    movmem2
  168. movmem1    ;want to move from bottom to top
  169.     mov    a,b
  170.     ora    c        ;while (n > 0) {
  171.     rz
  172.     mov    a,m
  173.     inx    h
  174.     stax    d
  175.     inx    d        ;    *des++ = *src++;
  176.     dcx    b        ;    n--;
  177.     BRA    movmem1        ;    }
  178.                 ;return
  179. movmem2    ;want to move from top to bottom
  180.     dad    b        ;    des += n;
  181.     xchg
  182.     dad    b
  183.     xchg            ;    src += n;
  184. movmem3    mov    a,b
  185.     ora    c        ;while (n > 0) {
  186.     rz
  187.     dcx    h
  188.     mov    a,m
  189.     dcx    d
  190.     stax    d        ;    *--des = *--src;
  191.     dcx    b        ;    n--;
  192.     BRA    movmem3        ;    }
  193.                 ;return
  194. movmem4    ;a little internal subroutine
  195.     mov    a,h
  196.     cmp    d
  197.     rc
  198.     mov    a,l
  199.     cmp    e
  200.     ret
  201.     PEND    MOVMEM
  202. ;
  203. ;
  204. ;    xchmem(src,des,n)
  205. ;    char *src,*des;
  206. ;    uint n;
  207. ;
  208. ;    Exchange the contents of two blocks of memory. NO special checks
  209. ;    are done for overlapping blocks, so the result in such a case may
  210. ;    be sort of strange. However, xchmem is very careful to handle a
  211. ;    count of zero properly.
  212. ;
  213.     PROC    XCHMEM
  214.     lhld    ARG3
  215.     mov    b,h
  216.     mov    c,l        ;n to BC
  217.     lhld    ARG2
  218.     xchg            ;des to DE
  219.     lhld    ARG1        ;src to HL
  220. xchmem1    mov    a,b
  221.     ora    c        ;while (n > 0) {
  222.     rz
  223.     mov    a,m
  224.     push    psw        ;    temp=*src;
  225.     ldax    d
  226.     mov    m,a        ;    *src=*des;
  227.     pop    a
  228.     stax    d        ;    *des=temp;
  229.     inx    h        ;    src++;
  230.     inx    d        ;    des++;
  231.     dcx    b        ;    n--;
  232.     BRA    xchmem1        ;    }
  233.     PEND    XCHMEM
  234. ;
  235. ;
  236. ;    fillbyte(data,des,n)
  237. ;    char data,*des;
  238. ;    uint n;
  239. ;
  240. ;    Fill n bytes of memory, starting at des, with data. The case of
  241. ;    a zero count is properly handled.
  242. ;
  243.     PROC    FILLBYTE
  244.     lhld    ARG3
  245.     mov    b,h
  246.     mov    c,l        ;n to BC
  247.     lhld    ARG1
  248.     xchg            ;data to E
  249.     lhld    ARG2        ;des to HL
  250. fillb1    mov    a,b
  251.     ora    c        ;while (n > 0) {
  252.     rz
  253.     mov    m,e        ;    *des=data;
  254.     inx    h        ;    des++;
  255.     dcx    b        ;    n--;
  256.     BRA    fillb1        ;    }
  257.     PEND    FILLBYTE
  258. ;
  259. ;
  260. ;    fillword(data,des,n)
  261. ;    int data,*des;
  262. ;    uint n;
  263. ;
  264. ;    Fill n words of memory, starting at des, with data. Note that 2*n
  265. ;    bytes will be filled, and that the case n==0 is properly handled.
  266. ;
  267.     PROC    FILLWORD
  268.     lhld    ARG3
  269.     mov    b,h
  270.     mov    c,l        ;n to BC
  271.     lhld    ARG1
  272.     xchg            ;data to DE
  273.     lhld    ARG2        ;des to HL
  274. fillw1:    mov    a,b
  275.     ora    c        ;while (n > 0) {
  276.     rz
  277.     mov    m,e
  278.     inx    h
  279.     mov    m,d
  280.     inx    h        ;    *des++ = data;
  281.     dcx    b        ;    n--;
  282.     BRA    fillw1        ;    }
  283.     PEND    FILLWORD
  284. ;
  285. ;
  286. ;    inp(port)
  287. ;    char port;
  288. ;
  289. ;    Returns the value input from I/O port # port. Returned value
  290. ;    is an integer with high byte set to zero.
  291. ;
  292.     PROC    INP
  293.     lda    ARG1
  294.     STAR    inp1+1
  295. inp1:    in    0        ;second byte of op is dynamically set
  296.     mov    l,a
  297.     mvi    h,0
  298.     ret
  299.     PEND    INP
  300. ;
  301. ;
  302. ;    outp(data,port)
  303. ;    char data,port;
  304. ;
  305. ;    Data is output to hardware port # port.
  306. ;
  307.     PROC    OUTP
  308.     lda    ARG2
  309.     STAR    outp1+1
  310.     lda    ARG1
  311. outp1:    out    0        ;second byte of op is dynamically set
  312.     ret
  313.     PEND    OUTP
  314. ;
  315. ;
  316. ;    peek(adr)
  317. ;    char *adr;
  318. ;
  319. ;    Returns the char pointed to by adr.
  320. ;
  321.     PROC    PEEK
  322.     lhld    ARG1
  323.     mov    l,m
  324.     mvi    h,0
  325.     ret
  326.     PEND    PEEK
  327. ;
  328. ;
  329. ;    poke(data,adr)
  330. ;    char data,*adr;
  331. ;
  332. ;    Stores data into memory pointed to by adr.
  333. ;
  334.     PROC    POKE
  335.     lda    ARG1
  336.     lhld    ARG2
  337.     mov    m,a
  338.     ret
  339.     PEND    POKE
  340. ;
  341. ;
  342. ;    peekw(adr)
  343. ;    int *adr;
  344. ;
  345. ;    Returns the integer pointed to by adr.
  346. ;
  347.     PROC    PEEKW
  348.     lhld    ARG1
  349.     mov    a,m
  350.     inx    h
  351.     mov    h,m
  352.     mov    l,a
  353.     ret
  354.     PEND    PEEKW
  355. ;
  356. ;
  357. ;    pokew(data,adr)
  358. ;    int data,*adr;
  359. ;
  360. ;    Stores data into memory pointed to by adr.
  361. ;
  362.     PROC    POKEW
  363.     lhld    ARG1
  364.     xchg
  365.     lhld    ARG2
  366.     mov    m,e
  367.     inx    h
  368.     mov    m,d
  369.     ret
  370.     PEND    POKEW
  371. ;
  372. ;
  373.     end
  374. q"≈E┼!    DM═┴╔)<MPUTCHA╥EXTDI╟f├    ├├:≈E!    w*∙Eδ`is#r!"≈E┼!    DM═┴!["≈E┼!    DM═┴`i~#fo"≈E┼!    DM═┴!    n&"≈E┼!    DM═┴╔(9MbCURSO╥PUTCHA╥PUT╙ï├ ├├├*≈Eδ`is#r*∙Eδ!    s#r*√Eδ!    s#r`i~#foσ!    ~#fo"∙Eß"≈E┼!    DM═┴!/*
  375.     this function converts ascii characters to an integer.
  376.     most common number bases may be used (except offset
  377.     octal).
  378. */
  379.  
  380. ntoi(n,b)
  381. char *n;
  382. int b;
  383. {
  384.     int val,sign;
  385.     char c;
  386.  
  387.     val=0; sign=1;
  388.     while ((c = *n) == '\t' || c == ' ') ++n;
  389.     if (c == '-') {sign = -1; n++;}
  390.     while (dig(c = *n++)) {
  391.        if (b == 16 && c >= 'A' && c <= 'F') c -= 7;
  392.        val = val * b + c - '0';
  393.     }
  394.     return sign*val;
  395. }
  396. /*
  397.     otoi(n)
  398.  
  399.     this function converts an offset octal number in ASCII
  400.     to an integer. the number is in the format xxx.xxx{a} and
  401.     may be preceeded by white space.
  402. */
  403.  
  404. otoi(n)
  405. char *n;
  406. {
  407.     int val, b, i;
  408.     char c;
  409.  
  410.     val = 0; b = 16384;
  411.  
  412.     while ((c = *n) == '\t' || c == ' ') ++n;
  413.     for (i = 0; i < 7; i++) {
  414.        if ((c = *n) == '.') {++n; b = 64;}
  415.        else {c = *n++; val = val + (b * (c - '0')); b /= 8;}
  416.     }
  417.     return val;
  418. }
  419.  
  420. /*------------------------------------------------------------------*/
  421. /*                                                                  */
  422. /*  This is a library of private routines for use with BDS C prog-  */
  423. /*  grams.  The comment lines preceding each entry are intended     */
  424. /*  to give a sufficient explanation of the routine that follows.   */
  425. /*  To link any of these routines to a BDS C program, merely name   */
  426. /*  PRVLIB as a argument following the name of the main program in  */
  427. /*  the CLINK command line.                                         */
  428. /*